//
//  BaseModel.m
//  iShow
//
//  Created by zhaohong on 16/2/29.
//  Copyright © 2016年 zhaohong. All rights reserved.
//

#import "BaseModel.h"
#include <objc/runtime.h>
@implementation BaseModel


-(id)initWithDataDic:(NSDictionary*)data{
    if (self = [super init]) {
        
        //判断返回的数据中是否有null，如果有则修改为空格，防止赋值崩溃
        NSMutableDictionary *muDictionary = [NSMutableDictionary dictionaryWithDictionary:data];
        NSArray *allKeys = [muDictionary allKeys];
        
        for (NSString *key in allKeys) {
            NSString *value = data[key];
            if ([value isEqual:[NSNull null]]) {
                value = @"";
                [muDictionary setObject:value forKey:key];
            }
        }
        [self setAttributes:muDictionary];
    }
    return self;
}

-(NSDictionary*)attributeMapDictionary{
    return nil;
}

-(SEL)getSetterSelWithAttibuteName:(NSString*)attributeName{
    NSString *capital = [[attributeName substringToIndex:1] uppercaseString];
    NSString *setterSelStr = [NSString stringWithFormat:@"set%@%@:",capital,[attributeName substringFromIndex:1]];
    return NSSelectorFromString(setterSelStr);
}
- (NSString *)customDescription{
    return nil;
}

- (NSString *)description{
    NSMutableString *attrsDesc = [NSMutableString stringWithCapacity:100];
    NSDictionary *attrMapDic = [self attributeMapDictionary];
    NSEnumerator *keyEnum = [attrMapDic keyEnumerator];
    id attributeName;
    
    while ((attributeName = [keyEnum nextObject])) {
        SEL getSel = NSSelectorFromString(attributeName);
        if ([self respondsToSelector:getSel]) {
            NSMethodSignature *signature = nil;
            signature = [self methodSignatureForSelector:getSel];
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
            [invocation setTarget:self];
            [invocation setSelector:getSel];
            NSObject *valueObj = nil;
            [invocation invoke];
            [invocation getReturnValue:&valueObj];
            //            ITTDINFO(@"attributeName %@ value %@", attributeName, valueObj);
            if (valueObj) {
                [attrsDesc appendFormat:@" [%@=%@] ",attributeName, valueObj];
                //[valueObj release];
            }else {
                [attrsDesc appendFormat:@" [%@=nil] ",attributeName];
            }
            
        }
    }
    
    NSString *customDesc = [self customDescription];
    NSString *desc;
    
    if (customDesc && [customDesc length] > 0 ) {
        desc = [NSString stringWithFormat:@"%@:{%@,%@}",[self class],attrsDesc,customDesc];
    }else {
        desc = [NSString stringWithFormat:@"%@:{%@}",[self class],attrsDesc];
    }
    
    return desc;
}
-(void)setAttributes:(NSDictionary*)dataDic{
    NSDictionary *attrMapDic = [self attributeMapDictionary];
    if (attrMapDic == nil) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[dataDic count]];
        for (NSString *key in dataDic) {
            [dic setValue:key forKey:key];
            attrMapDic = dic;
        }
    }
    NSEnumerator *keyEnum = [attrMapDic keyEnumerator];
    id attributeName;
    while ((attributeName = [keyEnum nextObject])) {
        SEL sel = [self getSetterSelWithAttibuteName:attributeName];
        if ([self respondsToSelector:sel]) {
        
            NSString *dataDicKey = [attrMapDic objectForKey:attributeName];
            id attributeValue = [dataDic objectForKey:dataDicKey];
            if (attributeValue == nil) {
                NSLog(@"=========");
            }
            

            
            [self performSelectorOnMainThread:sel
                                   withObject:attributeValue
                                waitUntilDone:[NSThread isMainThread]];
        }
    }
}
- (id)initWithCoder:(NSCoder *)decoder{
    if( self = [super init] ){
        NSDictionary *attrMapDic = [self attributeMapDictionary];
        if (attrMapDic == nil) {
            return self;
        }
        NSEnumerator *keyEnum = [attrMapDic keyEnumerator];
        id attributeName;
        while ((attributeName = [keyEnum nextObject])) {
            SEL sel = [self getSetterSelWithAttibuteName:attributeName];
            if ([self respondsToSelector:sel]) {
                id obj = [decoder decodeObjectForKey:attributeName];
                [self performSelectorOnMainThread:sel
                                       withObject:obj
                                    waitUntilDone:[NSThread isMainThread]];
            }
        }
    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder{
    NSDictionary *attrMapDic = [self attributeMapDictionary];
    if (attrMapDic == nil) {
        return;
    }
    NSEnumerator *keyEnum = [attrMapDic keyEnumerator];
    id attributeName;
    while ((attributeName = [keyEnum nextObject])) {
        SEL getSel = NSSelectorFromString(attributeName);
        if ([self respondsToSelector:getSel]) {
            NSMethodSignature *signature = nil;
            signature = [self methodSignatureForSelector:getSel];
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
            [invocation setTarget:self];
            [invocation setSelector:getSel];
            NSObject *valueObj = nil;
            [invocation invoke];
            [invocation getReturnValue:&valueObj];
            
            if (valueObj) {
                [encoder encodeObject:valueObj forKey:attributeName];
            }
        }
    }
}
- (NSData*)getArchivedData{
    return [NSKeyedArchiver archivedDataWithRootObject:self];
}

- (NSString *)cleanString:(NSString *)str {
    if (str == nil) {
        return @"";
    }
    NSMutableString *cleanString = [NSMutableString stringWithString:str];
    [cleanString replaceOccurrencesOfString:@"\n" withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, [cleanString length])];
    [cleanString replaceOccurrencesOfString:@"\r" withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, [cleanString length])];
    return cleanString;
}

#ifdef _FOR_DEBUG_
-(BOOL) respondsToSelector:(SEL)aSelector {
    //    printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
    return [super respondsToSelector:aSelector];
}
#endif


- (NSDictionary *)convertToDictionary
{
    int i;
    unsigned int propertyCount = 0;
    objc_property_t *propertyList = class_copyPropertyList([self class], &propertyCount);
    NSMutableDictionary *returnDic = [NSMutableDictionary dictionary];
    
    for ( i=0; i < propertyCount; i++ )
    {
        objc_property_t *thisProperty = propertyList + i;
        const char* propertyName = property_getName(*thisProperty);
        NSString *propertyKeyName = [NSString stringWithUTF8String:propertyName];
        [returnDic setValue:[self valueForKey:propertyKeyName]?[self valueForKey:propertyKeyName] : @""
                     forKey:propertyKeyName];
        //        NSLog(@"%@",propertyKeyName);
    }
    
    
    //获取字典所有的key
    NSArray *keys = [returnDic allKeys];
    for (i = 0; i<keys.count; i++) {
        
        //遍历字典看是否有数组
        NSString *keyName = keys[i];
        if ([returnDic[keyName] isKindOfClass:[NSArray class]]) {
            //获取数组内的内容
            NSArray *sonContentArray = returnDic[keyName];
            
            NSMutableArray *newSonContentArray = [NSMutableArray array];
            //遍历数组并将数组的model改为字典
            for (int j = 0; j<sonContentArray.count; j++) {
                
                id  deatilModel = sonContentArray[j];
              
              
                unsigned int propertyCount2 = 0;
                objc_property_t *propertyList = class_copyPropertyList([deatilModel class], &propertyCount2);
                NSMutableDictionary *returnSonDic = [NSMutableDictionary dictionary];
                
                for (int k=0; k < propertyCount2; k++ )
                {
                    objc_property_t *thisProperty = propertyList + k;
                    const char* propertyName = property_getName(*thisProperty);
                    NSString *propertyKeyName = [NSString stringWithUTF8String:propertyName];
                    [returnSonDic setValue:[deatilModel valueForKey:propertyKeyName]?[deatilModel valueForKey:propertyKeyName] : @""
                                 forKey:propertyKeyName];
                }
               
                [newSonContentArray addObject:returnSonDic];

            }
            //替换掉原有数组
            [returnDic setObject:newSonContentArray forKey:keyName];

        }
    }
    
    
    return returnDic;
}

@end
